import io
from PIL import Image
import PIL
import Logger_config

# 设置日志配置
logger = Logger_config.setup_logger()

class ImageUtil:
    SUPPORTED_FORMATS = {
        'png': 'PNG',
        'jpg': 'JPEG',
        'jpeg': 'JPEG',
        'webp': 'WEBP'
    }

    @staticmethod
    def _compress_image(image_data, max_size_kb=1024):
        """
        压缩图像数据，支持指定最大文件大小并优化格式

        参数:
            image_data: 图像的原始二进制数据
            max_size_kb: 最大允许大小（单位 KB），默认为 1024 KB (即 1 MB)

        返回:
            tuple: (compressed_data, img_format)
                compressed_data: 压缩后的图像二进制数据
                img_format: 压缩后的图像格式
        """
        try:
            if not image_data:
                logger.error("图像数据为空")
                return None, None
            
            img = Image.open(io.BytesIO(image_data))

            # 判断目标格式
            save_format = (img.format or "png").lower()
            final_format = ImageUtil.SUPPORTED_FORMATS.get(save_format, "PNG")

            # 初始缩放至合理尺寸
            img.thumbnail((1024, 1024), Image.Resampling.LANCZOS)
            img_byte_arr = io.BytesIO()
            quality = 85  # 初始画质

            # 保存初始图像
            if final_format in ['JPEG', 'WEBP']:
                img.save(img_byte_arr, format=final_format, quality=quality)
            elif final_format == 'GIF' and getattr(img, 'is_animated', False):
                img.save(img_byte_arr,format=final_format,save_all=True,duration=img.info.get('duration', 100),loop=img.info.get('loop', 0))
            else:
                img.save(img_byte_arr, format=final_format)

            # 如果已经满足大小要求则直接返回
            if len(img_byte_arr.getvalue()) <= max_size_kb * 1024:
                return img_byte_arr.getvalue(), save_format

            # 否则进行循环压缩
            while len(img_byte_arr.getvalue()) > max_size_kb * 1024 and img.size[0] > 50 and img.size[1] > 50:
                img = img.resize((int(img.size[0] * 0.9), int(img.size[1] * 0.9)), Image.Resampling.LANCZOS)
                img_byte_arr = io.BytesIO()  

                if final_format in ['JPEG', 'WEBP']:
                    quality = max(30, quality - 10)
                    img.save(img_byte_arr, format=final_format, quality=quality)
                elif final_format == 'PNG':
                    img.save(img_byte_arr, format=final_format, optimize=True, compress_level=6)  # 压缩级别1-9
                else:
                    img.save(img_byte_arr, format=final_format)

                # 添加提前退出条件
                if len(img_byte_arr.getvalue()) <= max_size_kb * 1024:
                    break

            compressed_data = img_byte_arr.getvalue()
            if not compressed_data:
                logger.error("压缩后的图像数据为空")
                return None, save_format
            else:
                return compressed_data, save_format

        except IOError as io_err:
            logger.error(f"IO错误: {io_err}")
        except PIL.UnidentifiedImageError:
            logger.error("无法识别的图像格式")
        except Exception as e:
            logger.error(f"未知错误: {e}")
            raise